/* ===================

AX2E (AXESCON XACML 2.0 Engine) is the Java authorization engine, which implements OASIS XACML 2.0 standard.
Copyright (C) 2007 AXESCON LLC

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA


Contact: AXESCON LLC - info{at}axescon.com

 =================== */
package axescon.xacml.api;

import axescon.xacml.model.policy.AttributeValue;

/**
 * @author argyn
 *         Date: Oct 31, 2005
 *         Time: 8:50:24 PM
 *         Responsibilities:
 * represents Function or Expression evaluation result, which can be a single value or a bag.
 * Single values is represented by AttributeValue, and bag ia AttributeValue[] array.
 */
public class Liquid {

    /**
     * construct a single value result using given value
     * @param value single value
     */
    public Liquid(AttributeValue value) {
        this.value = value;
    }

    public Liquid() {
    }


    /**
     * builds result representing empty bag
     * @return ampty bag result
     */
    public static Liquid newEmptyBag(){
        Liquid ret = new Liquid();
        ret.isBag=true;
        return ret;
    }

    /**
     * constructs bag result using given array of values
     * @param value array of attribute values
     */
    public Liquid(AttributeValue[] value) {
        this.value = value;
        isBag=true;
    }

    /**
     * either AttributeValue or AttributeValue[]
     */
    Object value;

    /**
     * gets result value as Object, it can be both single value and bag
     * @return result value
     */
    public Object getValue() {
        return value;
    }

    /**
     * sets result value using given Object, which can be either AttributeValue or AttributeValue[] array (for bags)
     * @param value
     * @throws XacmlException when Object is incorrect
     */
    public void setValue(Object value) throws XacmlException{
        if(value!=null){
            if(value instanceof AttributeValue)setBag(false);
            else if(value instanceof AttributeValue[]){
                setBag(true);
            }else{
                throw new XacmlException(value.toString()
                        ,XacmlException.ERR_CODE_PROCESSING_EXPR_BAD_EVAL_RESULT);
            }
        }
        this.value = value;
    }

    /**
     * true if this represents bag
     */
    boolean isBag;

    /**
     * indicates if this is bag result
     * @return true if this represents bag
     */
    public boolean isBag() {
        return isBag;
    }

    /**
     * sets bag result indicator
     * @param bag when true, result considered as bag
     */
    public void setBag(boolean bag) {
        isBag = bag;
    }

    /**
     * returns a bag encapsulated in this result
     * @return AttributeValue[] array representing bag value
     * @exception ExpressionEvalIndeterminateException if it's not a bag
     */
    public AttributeValue[] getBag()throws ExpressionEvalIndeterminateException{
        if(isBag()) return (AttributeValue[])value;
        throw new ExpressionEvalIndeterminateException("not a bag"
                ,XacmlException.ERR_CODE_PROCESSING_EXPR_NOT_BAG);
    }

    /**
     * returns a bag encapsulated in this result. this method assumes that
     * this result is bag type
     * @return AttributeValue[] array representing bag value
     */
    public AttributeValue[] getBagUnsafe(){
         return (AttributeValue[])value;
    }

    /**
     * returns a single value encapsulated in this result
     * @return AttributeValue representing value
     * @exception ExpressionEvalIndeterminateException if it's a bag
     */
    public AttributeValue getSingular()throws ExpressionEvalIndeterminateException{
        if(!isBag()) return (AttributeValue)value;
        throw new ExpressionEvalIndeterminateException("bag"
                ,XacmlException.ERR_CODE_PROCESSING_EXPR_NOT_SINGULAR);
    }

    /**
     * returns a single value encapsulated in this result. this method assumes that
     * this result is NOT bag type
     * @return AttributeValue representing single value
     */
    public AttributeValue getSingularUnsafe(){
        return (AttributeValue)value;
    }
}
